﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HDJ.Framework.Core
{
    
    /// <summary>
    /// 动态数据，可监听记录Value变化
    /// </summary>
    public class DynamicValue
    {
        public delegate void ValueChangeEvent(DynamicValue dynamicValue, object nowValue, object lastValue);

        private object m_value;
        private int storeIndex = -1;
        private bool m_isChange;
        private bool m_isRecordChange;
        /// <summary>
        /// 内部操作，undo，redo
        /// </summary>
        private bool m_isAutotrace = false;
        private List<object> recordValues;
        /// <summary>
        /// 当Value变化时回调
        /// </summary>
        public event ValueChangeEvent onValueChangeEvent;
        public object Value
        {
            get
            {
                return m_value;
            }
            set
            {
                if (!m_value.Equals(value))
                {
                    object lastValue = m_value;
                    m_value = value;

                    if (onValueChangeEvent != null)
                        onValueChangeEvent(this, value, lastValue);
                    m_isChange = true;
                    if (m_isRecordChange && !m_isAutotrace)
                    {
                        recordValues.Add(value);
                    }
                }
            }
        }

        public bool IsChange
        {
            get
            {
                return m_isChange;
            }
        }
        public bool IsRecordChange
        {
            get
            {
                return m_isRecordChange;
            }
        }

        public DynamicValue(object baseValue,bool isRecordChange)
        {
            m_value = baseValue;
            m_isChange = false;
            this.m_isRecordChange = isRecordChange;
            if (isRecordChange)
            {
                recordValues = new List<object>();
                recordValues.Add(baseValue);
            }
        }
        /// <summary>
        /// 在记录变化前提下，调用该方法可以将当前值作为存储的位置，在使用撤销，前进操作时，到了这个位置将作为 m_isChange == false
        /// </summary>
        public void StoreValue()
        {
            if (m_isRecordChange)
            {
                storeIndex = recordValues.IndexOf(m_value);
                m_isChange = false;
                
            }
        }
        /// <summary>
        /// 撤销
        /// </summary>
        public void Undo(bool isSendChangeEvent)
        {
            if (m_isRecordChange)
            {
                int index = recordValues.IndexOf(m_value);
                if (index == 0)
                    return;
                index--;

                if (isSendChangeEvent)
                {
                    m_isAutotrace = true;
                    Value = recordValues[index];
                    m_isAutotrace = false;
                }
                else
                {
                    m_value = recordValues[index];
                }
                if (index == storeIndex)
                {
                    m_isChange = false;
                }
                else
                {
                    m_isChange = true;
                }
            }
           
        }
        /// <summary>
        /// 重做
        /// </summary>
        public void Redo(bool isSendChangeEvent)
        {
            if (m_isRecordChange)
            {
                int index = recordValues.IndexOf(m_value);
                if (index == recordValues.Count-1)
                    return;
                index++;
                if (isSendChangeEvent)
                {
                    m_isAutotrace = true;
                    Value = recordValues[index];
                    m_isAutotrace = false;
                }
                else
                {
                    m_value = recordValues[index];
                }
                if (index == storeIndex)
                {
                    m_isChange = false;
                }
                else
                {
                    m_isChange = true;
                }
            }
        }

        public override string ToString()
        {
            return Value.ToString();
        }
    }
}
